home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-02 / pas_all.zip / TI229.ASC < prev    next >
Text File  |  1992-08-12  |  8KB  |  331 lines

  1.  
  2.  
  3.  
  4.  
  5.  
  6.  
  7.  
  8.  
  9.   PRODUCT : TURBO PASCAL                               NUMBER : 229
  10.   VERSION : All
  11.        OS : PC-DOS, MS-DOS
  12.      DATE : August 1, 1986                               PAGE : 1/5
  13.     TITLE : EXECUTE SUBPROCESS CALL
  14.  
  15.  
  16.  
  17.  
  18.   The following example routines are public domain programs that
  19.   have been uploaded to our Forum on CompuServe. As a courtesy to
  20.   our users that do not have immediate access to CompuServe,
  21.   Technical Support distributes these routines free of charge.
  22.  
  23.   However, because these routines are public domain programs, not
  24.   developed by Borland International, we are unable to provide any
  25.   technical support or assistance using these routines. If you need
  26.   assistance using these routines, or are experiencing difficu
  27.  
  28.   { EXEC.PAS version 1.3
  29.  
  30.   This program contains two functions that allow you to run other
  31.   programs from within a Turbo Pascal program. The first function,
  32.   SubProcess, actually calls a different program using MS-DOS call
  33.   4BH, EXEC. The second function, GetComSpec, returns the pat
  34.  
  35.   }
  36.   Program Exec;
  37.   Type
  38.     Str66=String[66];
  39.     Str255=String[255];
  40.  
  41.   Function SubProcess(CommandLine: Str255): Integer;
  42.     { Pass this function a string of the form
  43.         'D:\FULL\PATH\NAME\OF\FILE.TYP parameter1 parameter2 ...'
  44.  
  45.       For example,
  46.         'C:\SYSTEM\CHKDSK.COM'
  47.         'A:\WS.COM DOCUMENT.1'
  48.         'C:\DOS\LINK.EXE TEST;'
  49.         'C:\COMMAND.COM /C COPY *.* B:\BACKUP >FILESCOP.IED'
  50.  
  51.  
  52.   The third example shows several things. To do any of the
  53.   following, you must invoke the command processor and let it do
  54.   the work: redirection; piping; path searching; searching for the
  55.   extension of a program (.COM, .EXE, or .BAT); batch files; and
  56.   interna
  57.  
  58.   Actual example:
  59.     I:=SubProcess(GetComSpec+' /C COPY *.* B:\BACKUP
  60.   >FILESCOP.IED');
  61.  
  62.  
  63.  
  64.  
  65.  
  66.  
  67.  
  68.  
  69.  
  70.  
  71.  
  72.  
  73.  
  74.  
  75.   PRODUCT : TURBO PASCAL                               NUMBER : 229
  76.   VERSION : All
  77.        OS : PC-DOS, MS-DOS
  78.      DATE : August 1, 1986                               PAGE : 2/5
  79.     TITLE : EXECUTE SUBPROCESS CALL
  80.  
  81.  
  82.  
  83.  
  84.   The value returned is the result returned by DOS after the EXEC
  85.   call. The most common values are:
  86.  
  87.        0: Success
  88.        1: Invalid function (should never happen with this routine)
  89.        2: File/path not found
  90.        8: Not enough memory to load program
  91.       10: Bad environment (greater than 32K)
  92.       11: Illegal .EXE file format
  93.  
  94.   If you get any other result, consult an MS-DOS Technical
  95.   Reference manual.
  96.  
  97.   VERY IMPORTANT NOTE: you MUST use the Options menu of Turbo
  98.   Pascal to restrict the amount of free dynamic memory used by your
  99.   program. Only the memory that is not used by the heap is
  100.   available for use by other programs. }
  101.  
  102.     Const
  103.       SSSave: Integer=0;
  104.       SPSave: Integer=0;
  105.  
  106.     Var
  107.       Regs: Record Case Integer Of
  108.               1: (AX,BX,CX,DX,BP,SI,DI,DS,ES,Flags: Integer);
  109.               2: (AL,AH,BL,BH,CL,CH,DL,DH: Byte);
  110.             End;
  111.       FCB1,FCB2: Array [0..36] Of Byte;
  112.       PathName: Str66;
  113.       CommandTail: Str255;
  114.       ParmTable: Record
  115.                    EnvSeg: Integer;
  116.                    ComLin: ^Integer;
  117.                    FCB1Pr: ^Integer;
  118.                    FCB2Pr: ^Integer;
  119.                  End;
  120.       I,RegsFlags: Integer;
  121.  
  122.     Begin
  123.       If Pos(' ',CommandLine)=0 Then
  124.        Begin
  125.         PathName:=CommandLine+#0;
  126.         CommandTail:=^M;
  127.  
  128.  
  129.  
  130.  
  131.  
  132.  
  133.  
  134.  
  135.  
  136.  
  137.  
  138.  
  139.  
  140.  
  141.   PRODUCT : TURBO PASCAL                               NUMBER : 229
  142.   VERSION : All
  143.        OS : PC-DOS, MS-DOS
  144.      DATE : August 1, 1986                               PAGE : 3/5
  145.     TITLE : EXECUTE SUBPROCESS CALL
  146.  
  147.  
  148.  
  149.  
  150.        End
  151.       Else
  152.        Begin
  153.         PathName:=Copy(CommandLine,1,Pos(' ',CommandLine)-1)+#0;
  154.         CommandTail:=Copy(CommandLine,Pos(' ',CommandLine),255)+^M;
  155.        End;
  156.       CommandTail[0]:=Pred(CommandTail[0]);
  157.       With Regs Do
  158.        Begin
  159.         FillChar(FCB1,Sizeof(FCB1),0);
  160.         AX:=$2901;
  161.         DS:=Seg(CommandTail[1]);
  162.         SI:=Ofs(CommandTail[1]);
  163.         ES:=Seg(FCB1);
  164.         DI:=Ofs(FCB1);
  165.         MsDos(Regs); { Create FCB 1 }
  166.         FillChar(FCB2,Sizeof(FCB2),0);
  167.         AX:=$2901;
  168.         ES:=Seg(FCB2);
  169.         DI:=Ofs(FCB2);
  170.         MsDos(Regs); { Create FCB 2 }
  171.         ES:=CSeg;
  172.         BX:=SSeg-CSeg+MemW[CSeg:MemW[CSeg:$0101]+$112];
  173.         AH:=$4A;
  174.         MsDos(Regs); { Deallocate unused memory }
  175.         With ParmTable Do
  176.          Begin
  177.           EnvSeg:=MemW[CSeg:$002C];
  178.           ComLin:=Addr(CommandTail);
  179.           FCB1Pr:=Addr(FCB1);
  180.           FCB2Pr:=Addr(FCB2);
  181.          End;
  182.  
  183.      InLine($8D/$96/ PathName /$42/  { <DX>:=Ofs(PathName[1]); }
  184.             $8D/$9E/ ParmTable /     { <BX>:=Ofs(ParmTable);   }
  185.             $B8/$00/$4B/             { <AX>:=$4B00;            }
  186.             $1E/$55/                 { Save <DS>, <BP>         }
  187.             $16/$1F/                 { <DS>:=Seg(PathName[1]); }
  188.             $16/$07/                 { <ES>:=Seg(ParmTable);   }
  189.             $2E/$8C/$16/ SSSave /    { Save <SS> in SSSave     }
  190.             $2E/$89/$26/ SPSave /    { Save <SP> in SPSave     }
  191.             $FA/                     { Disable interrupts      }
  192.             $CD/$21/                 { Call MS-DOS             }
  193.  
  194.  
  195.  
  196.  
  197.  
  198.  
  199.  
  200.  
  201.  
  202.  
  203.  
  204.  
  205.  
  206.  
  207.   PRODUCT : TURBO PASCAL                               NUMBER : 229
  208.   VERSION : All
  209.        OS : PC-DOS, MS-DOS
  210.      DATE : August 1, 1986                               PAGE : 4/5
  211.     TITLE : EXECUTE SUBPROCESS CALL
  212.  
  213.  
  214.  
  215.  
  216.             $FA/                     { Disable interrupts      }
  217.             $2E/$8B/$26/ SPSave /    { Restore <SP>            }
  218.             $2E/$8E/$16/ SSSave /    { Restore <SS>            }
  219.             $FB/                     { Enable interrupts       }
  220.             $5D/$1F/                 { Restore <BP>,<DS>       }
  221.             $9C/$8F/$86/ RegsFlags / { Flags:=<CPU flags>      }
  222.             $89/$86/ Regs );         { Regs.AX:=<AX>;          }
  223.  
  224.   { The manipulation of SS and SP is necessary because  under DOS
  225.   2.x, after returning from an EXEC call, ALL  registers are
  226.   destroyed except CS and IP! }
  227.  
  228.         If (RegsFlags And 1)<>0 Then SubProcess:=AX
  229.         Else SubProcess:=0;
  230.        End;
  231.     End;
  232.  
  233.   Function GetComSpec: Str66;
  234.     Type
  235.       Env=Array [0..32767] Of Char;
  236.     Var
  237.       EPtr: ^Env;
  238.       EStr: Str255;
  239.       Done: Boolean;
  240.       I: Integer;
  241.  
  242.     Begin
  243.       EPtr:=Ptr(MemW[CSeg:$002C],0);
  244.       I:=0;
  245.       Done:=False;
  246.       EStr:='';
  247.       Repeat
  248.         If EPtr^[I]=#0 Then
  249.          Begin
  250.           If EPtr^[I+1]=#0 Then Done:=True;
  251.           If Copy(EStr,1,8)='COMSPEC=' Then
  252.            Begin
  253.             GetComSpec:=Copy(EStr,9,100);
  254.             Done:=True;
  255.            End;
  256.           EStr:='';
  257.          End
  258.         Else EStr:=EStr+EPtr^[I];
  259.  
  260.  
  261.  
  262.  
  263.  
  264.  
  265.  
  266.  
  267.  
  268.  
  269.  
  270.  
  271.  
  272.  
  273.   PRODUCT : TURBO PASCAL                               NUMBER : 229
  274.   VERSION : All
  275.        OS : PC-DOS, MS-DOS
  276.      DATE : August 1, 1986                               PAGE : 5/5
  277.     TITLE : EXECUTE SUBPROCESS CALL
  278.  
  279.  
  280.  
  281.  
  282.         I:=I+1;
  283.       Until Done;
  284.     End;
  285.  
  286.   { Example program. Set both mInimum and mAximum free dynamic
  287.   memory to 100 and compile this to a .COM file. Delete the  next
  288.   line to enable: }
  289.  
  290.   Var Command: Str255;
  291.       I: Integer;
  292.  
  293.   Begin
  294.     Write('Enter a * to quit; put a * before a ');
  295.     Writeln('command to use COMMAND.COM.');
  296.     Repeat
  297.       Write('=->');
  298.       ReadLn(Command);
  299.       If Command='*' Then Halt;
  300.       If Command<>'' Then
  301.        Begin
  302.         If Command[1]='*' Then
  303.            Command:=GetComSpec+' /C '+Copy(Command,2,255);
  304.         I:=SubProcess(Command);
  305.         If I<>0 Then WriteLn('Error - ',I);
  306.        End;
  307.     Until False;
  308.   End.
  309.  
  310.   DISCLAIMER: You have the right to use this technical information
  311.   subject to the terms of the No-Nonsense License Statement that
  312.   you received with the Borland product to which this information
  313.   pertains.
  314.  
  315.  
  316.  
  317.  
  318.  
  319.  
  320.  
  321.  
  322.  
  323.  
  324.  
  325.  
  326.  
  327.  
  328.  
  329.  
  330.  
  331.